package com.token.sysflow.webservice;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.token.base.Pl;
import com.token.sql.IntegrateSql;
import com.token.sysflow.core.FlowHandlerService;
import com.token.sysflow.enumerate.ActionTypeEnum;
import com.token.sysflow.impl.*;
import com.token.webservice.WebServiceMainImpl;

/**
 * @author chenjianxiong 2020/6/21
 */
public class FlowWebServiceMain extends WebServiceMainImpl {

    private String keyUnid;

    private String selectApprovers;

    private String stepId;

    private String flowId;

    private String opinions;

    private String result;

    private ActionTypeEnum actionType;

    private AbstractFlowHandlerImpl handler;

    @Override
    public void setInDataStr(String jsonString) throws Exception {
        try {
            inData = JSON.parseObject(jsonString);
        } catch (JSONException e) {
            e.printStackTrace();
            throw new Exception("传入的Json字符串异常：" + jsonString);
        }
        keyUnid = inData.getString("keyUnid");
        selectApprovers = inData.getString("selectApprovers");
        stepId = inData.getString("stepId");
        flowId = inData.getString("flowId");
        opinions = inData.getString("opinions");
        result = inData.getString("result");
    }

    @Override
    public void start(IntegrateSql iSql) throws Exception {
        try {
            handler = getFlowHandlerByType();
            FlowHandlerService service = new FlowHandlerService(iSql);
            service.execute(handler);
        } catch (Exception e) {
            e.printStackTrace();
            if (handler == null) {
                handler = new LoadFlowStepImpl();
            }
            handler.handleReturnErr(e);
        }
    }

    @Override
    public JSONObject getResult() {
        return handler.getResult();
    }


    /**
     * 操作类型
     * @param actionType
     */
    public void setActionType(ActionTypeEnum actionType){
        this.actionType = actionType;
        this.setActionTypeId(this.actionType.getId());
        this.setActionTypeName(this.actionType.getName());
    }

    /**
     *
     * @param impl
     * @throws Exception
     */
    private void publicParam(AbstractFlowHandlerImpl impl) throws Exception {
        impl.setActionTimer(Pl.getCurDataTime());
        impl.setSysId(Pl.getSysId());
        impl.setActionUser(needValue(inData.getString("actionUser"), "当前用户", "actionUser"));
        if (opinions != null) {
            impl.setOpinions(opinions);
        }
    }

    /**
     *
     * @return
     * @throws Exception
     */
    private AbstractFlowHandlerImpl getLoadFlowStepImpl() throws Exception {
        LoadFlowStepImpl impl = new LoadFlowStepImpl();
        publicParam(impl);
        if (this.keyUnid == null || "".equals(keyUnid)) {
            impl.setLoadType(LoadFlowStepImpl.TYPE_FIRST);
            impl.setAppKeyId(needValue(inData.getString("appKeyId"), "应用KEYId", "appKeyId"));
            impl.setApplyer(needValue(inData.getString("applyer"), "申请人", "applyer"));
        } else {
            impl.setLoadType(LoadFlowStepImpl.TYPE_APPROVAL);
            impl.setKeyUnid(keyUnid);
        }
        return impl;
    }

    private AbstractFlowHandlerImpl getPathApproverImpl() throws Exception {
        GetPathApproverImpl impl = new GetPathApproverImpl();
        publicParam(impl);
        if (this.keyUnid == null || "".equals(keyUnid)) {
            impl.setFlowId(needValue(inData.getString("flowId"), "流程Id", "flowId"));
            impl.setStepId(inData.getString("stepId")); //环节ID不传时，默认取开始环节。
            impl.setApplyer(needValue(inData.getString("applyer"), "申请人", "applyer"));
            impl.setCreater(needValue(inData.getString("creater"), "起草人", "creater"));
        } else {
            impl.setKeyUnid(keyUnid);
        }
        impl.setFieldValues(inData.getJSONObject("fieldValues"));
        return impl;
    }

    private AbstractFlowHandlerImpl getSubmitFlowImpl() throws Exception {
        SubmitFlowImpl impl = new SubmitFlowImpl();
        publicParam(impl);
        //起草第一次提交时
        if (keyUnid == null || "".equals(keyUnid)) {
            impl.setFlowId(needValue(inData.getString("flowId"), "流程Id", "flowId"));
            impl.setAppKeyId(needValue(inData.getString("appKeyId"), "应用KEYId", "appKeyId"));
            impl.setApplyer(needValue(inData.getString("applyer"), "申请人", "applyer"));
            impl.setCreater(needValue(inData.getString("creater"), "起草人", "creater"));
            impl.setFirstSubmit(true);
        } else {
            impl.setKeyUnid(keyUnid);
            impl.setFirstSubmit(false);
            impl.setSubKeyUnid(inData.getString("subKeyUnid")); //子流程
        }


        //办理人，会签会审不用传selectApprovers
        if (selectApprovers != null && !"".equals(selectApprovers)) {
            impl.setSelectApprover(selectApprovers.split(";"));
        }

        //指定环节Id，会签会审不用传stepId
        if (stepId != null && !"".equals(stepId)) {
            impl.setStepId(stepId);
        }

        //会审传入
        if (result != null && !result.equals("")) {
            impl.setHSResult(result.equals("1") ? SubmitFlowImpl.HSResult_YES : SubmitFlowImpl.HSResult_NO);
        }


        //表单字段的值传入。
        impl.setFieldValues(inData.getJSONObject("fieldValues"));
        return impl;
    }

    private AbstractFlowHandlerImpl getReturnStepImpl() throws Exception {
        GetReturnStepImpl impl = new GetReturnStepImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        return impl;
    }

    private AbstractFlowHandlerImpl getReturnFlowImpl() throws Exception {
        ReturnFlowImpl impl = new ReturnFlowImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        impl.setStepId(needValue(stepId, "环节Id", "stepId"));
        impl.setFlowId(needValue(flowId, "流程Id", "flowId"));
        String approver = needValue(selectApprovers, "退回办理人", "selectApprovers");
        impl.setSelectApprover(approver.split(";"));
        return impl;
    }

    private AbstractFlowHandlerImpl getBackFlowImpl() throws Exception {
        BackFlowImpl impl = new BackFlowImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        return impl;
    }

    private AbstractFlowHandlerImpl getOverFlowImpl() throws Exception {
        OverFlowImpl impl = new OverFlowImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        return impl;
    }

    private AbstractFlowHandlerImpl getSysSetFlowImpl() throws Exception {
        SysSetFlowImpl impl = new SysSetFlowImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        String approver = needValue(selectApprovers, "审批人", "selectApprovers");
        impl.setSelectApprover(approver.split(";"));
        impl.setStepId(needValue(stepId, "环节Id", "stepId"));
        impl.setFlowId(needValue(flowId, "流程Id", "flowId"));
        return impl;
    }

    private AbstractFlowHandlerImpl getTransmitFlowImpl() throws Exception {
        TransmitFlowImpl impl = new TransmitFlowImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        String approver = needValue(selectApprovers, "转审人", "selectApprovers");
        impl.setSelectApprover(approver.split(";"));
        return impl;
    }

    private AbstractFlowHandlerImpl getCreateCallHQImpl() throws Exception {
        CreateCallHQImpl impl = new CreateCallHQImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        String approver = needValue(selectApprovers, "会签人", "selectApprovers");
        impl.setSelectApprover(approver.split(";"));
        return impl;
    }

    private AbstractFlowHandlerImpl getCreateCallHSImpl() throws Exception {
        CreateCallHSImpl impl = new CreateCallHSImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        impl.setHSWay(needValue(inData.getString("hsway"), "策略条件", "hsway"));
        String approver = needValue(selectApprovers, "会审人", "selectApprovers");
        impl.setSelectApprover(approver.split(";"));
        return impl;
    }

    private AbstractFlowHandlerImpl getCCFlowImpl() throws Exception {
        CCFlowImpl impl = new CCFlowImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));

        String approver = needValue(selectApprovers, "抄送人", "selectApprovers");
        impl.setSelectApprover(approver.split(";"));
        return impl;
    }

    private AbstractFlowHandlerImpl getUrgFlowImpl() throws Exception {
        UrgFlowImpl impl = new UrgFlowImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        impl.setOpinions(needValue(opinions, "意见", "opinions"));
        return impl;
    }

    private AbstractFlowHandlerImpl getApproveProcessImpl() throws Exception {
        GetApproveProcessImpl impl = new GetApproveProcessImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        impl.setApproveLog(inData.getIntValue("approveLog")); //1 输出办理意见 0 不输出。
        return impl;
    }

    private AbstractFlowHandlerImpl getOpinionsImpl() throws Exception {
        GetOpinionsImpl impl = new GetOpinionsImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        return impl;
    }

    private AbstractFlowHandlerImpl getFlowApproveLogImpl() throws Exception {
        GetFlowApproveLogImpl impl = new GetFlowApproveLogImpl();
        publicParam(impl);
        impl.setKeyUnid(needValue(keyUnid, "关联Id", "keyUnid"));
        return impl;
    }

    /**
     * @return AbstractFlowHandlerImpl
     */
    private AbstractFlowHandlerImpl getFlowHandlerByType() throws Exception {
        //根据提交类型来获取对应的处理类
        if (this.actionType == null) {
            throw new Exception("接口的操作类型[actionType]必须传入！");
        }

        //获取类型
        switch (actionType) {
            case LOADFLOW:
                return getLoadFlowStepImpl();
            case GETPATH:
                return getPathApproverImpl();
            case GETRETRUNPATH:
                return getReturnStepImpl();
            case SUBMIT:
                return getSubmitFlowImpl();
            case RETURN:
                return getReturnFlowImpl();
            case BACK:
                return getBackFlowImpl();
            case OVER:
                return getOverFlowImpl();
            case TOFLOW:
                return getSysSetFlowImpl();
            case TRANSMIT:
                return getTransmitFlowImpl();
            case CALLHQ:
                return getCreateCallHQImpl();
            case CALLHS:
                return getCreateCallHSImpl();
            case CC:
                return getCCFlowImpl();
            case URG:
                return getUrgFlowImpl();
            case APPROVEPROCESS:
                return getApproveProcessImpl();
            case OPINIONS:
                return getOpinionsImpl();
            case FLOWAPPROVELOG:
                return getFlowApproveLogImpl();
            default:
                throw new Exception("actionType 接口类型不明确！");
        }
    }
}
